from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from typing import List, Optional
from datetime import datetime
from ..db import get_db
from .. import models, schemas
from ..security import get_current_user

router = APIRouter()

@router.post("/", response_model=schemas.KnowledgeOut)
def create_knowledge(payload: schemas.KnowledgeCreate, db: Session = Depends(get_db), current=Depends(get_current_user)):
    k = models.Knowledge(title=payload.title, summary=payload.summary, body=payload.body, owner_id=current.id)
    db.add(k)
    db.commit()
    db.refresh(k)
    return k

@router.post("", response_model=schemas.KnowledgeOut)
def create_knowledge_noslash(payload: schemas.KnowledgeCreate, db: Session = Depends(get_db), current=Depends(get_current_user)):
    """Alias without trailing slash to avoid 307 redirect from /api/knowledge to /api/knowledge/ on POST."""
    return create_knowledge(payload, db, current)


@router.get("/", response_model=List[schemas.KnowledgeOut])
def list_knowledge(db: Session = Depends(get_db), current=Depends(get_current_user), folder_id: Optional[int] = None, trash: bool = False):
    q = db.query(models.Knowledge).filter(models.Knowledge.owner_id == current.id)
    if trash:
        q = q.filter(models.Knowledge.is_deleted == True)
    else:
        q = q.filter(models.Knowledge.is_deleted == False)
        if folder_id is not None:
            q = q.join(models.KnowledgeFolderLink, models.KnowledgeFolderLink.knowledge_id == models.Knowledge.id).filter(models.KnowledgeFolderLink.folder_id == folder_id)
    return q.order_by(models.Knowledge.created_at.desc()).all()


@router.get("", response_model=List[schemas.KnowledgeOut])
def list_knowledge_noslash(db: Session = Depends(get_db), current=Depends(get_current_user), folder_id: Optional[int] = None, trash: bool = False):
    """Alias without trailing slash to avoid 307 redirect between /api/knowledge and /api/knowledge/."""
    return list_knowledge(db, current, folder_id, trash)

@router.get("/{kid}", response_model=schemas.KnowledgeOut)
def get_knowledge(kid: int, db: Session = Depends(get_db), current=Depends(get_current_user)):
    k = db.query(models.Knowledge).filter(models.Knowledge.id == kid, models.Knowledge.owner_id == current.id).first()
    if not k:
        raise HTTPException(status_code=404, detail="Knowledge not found")
    
    # Fetch review stats
    from sqlalchemy import func
    logs = db.query(models.ReviewLog.card_id, func.count(models.ReviewLog.id), func.max(models.ReviewLog.reviewed_at)).filter(
        models.ReviewLog.knowledge_id == kid,
        models.ReviewLog.owner_id == current.id
    ).group_by(models.ReviewLog.card_id).all()
    
    stats = {card_id: {"count": count, "last_reviewed": last} for card_id, count, last in logs}
    
    # Inject stats into body (hacky but effective for now without changing schema)
    # Ideally we should return a separate field, but frontend expects KnowledgeOut which mirrors model.
    # We can attach it to the response if we change the schema.
    # For now, let's just return it as a separate field in a new schema or just let frontend fetch it separately?
    # User asked to "回显到知识点详情页面的问题卡片右上角".
    # Let's modify the response to include stats.
    # But schemas.KnowledgeOut is Pydantic model.
    # We can dynamically add it or update the schema.
    # Let's update the schema in schemas.py first? Or just return a dict.
    # Returning a dict is easier but breaks type safety.
    # Let's return a dict with extra fields.
    
    k_dict = {c.name: getattr(k, c.name) for c in k.__table__.columns}
    k_dict["review_stats"] = stats
    return k_dict

@router.put("/{kid}", response_model=schemas.KnowledgeOut)
def update_knowledge(kid: int, payload: schemas.KnowledgeCreate, db: Session = Depends(get_db), current=Depends(get_current_user)):
    k = db.query(models.Knowledge).filter(models.Knowledge.id == kid, models.Knowledge.owner_id == current.id).first()
    if not k:
        raise HTTPException(status_code=404, detail="Knowledge not found")
    k.title = payload.title
    k.summary = payload.summary
    k.body = payload.body
    db.commit()
    db.refresh(k)
    return k

@router.delete("/{kid}")
def delete_knowledge(kid: int, db: Session = Depends(get_db), current=Depends(get_current_user)):
    k = db.query(models.Knowledge).filter(models.Knowledge.id == kid, models.Knowledge.owner_id == current.id).first()
    if not k:
        raise HTTPException(status_code=404, detail="Knowledge not found")
    # Soft delete
    k.is_deleted = True
    k.deleted_at = datetime.utcnow()
    db.commit()
    return {"ok": True}

@router.post("/{kid}/restore")
def restore_knowledge(kid: int, db: Session = Depends(get_db), current=Depends(get_current_user)):
    k = db.query(models.Knowledge).filter(models.Knowledge.id == kid, models.Knowledge.owner_id == current.id).first()
    if not k:
        raise HTTPException(status_code=404, detail="Knowledge not found")
    k.is_deleted = False
    k.deleted_at = None
    db.commit()
    return {"ok": True}

@router.delete("/{kid}/hard")
def hard_delete_knowledge(kid: int, db: Session = Depends(get_db), current=Depends(get_current_user)):
    k = db.query(models.Knowledge).filter(models.Knowledge.id == kid, models.Knowledge.owner_id == current.id).first()
    if not k:
        raise HTTPException(status_code=404, detail="Knowledge not found")
    db.delete(k)
    db.commit()
    return {"ok": True}

@router.delete("/trash/empty")
def empty_trash(db: Session = Depends(get_db), current=Depends(get_current_user)):
    db.query(models.Knowledge).filter(models.Knowledge.owner_id == current.id, models.Knowledge.is_deleted == True).delete()
    db.commit()
    return {"ok": True}

@router.post("/{kid}/folder")
def set_knowledge_folder(kid: int, payload: schemas.IssueSetFolderIn, db: Session = Depends(get_db), current=Depends(get_current_user)):
    k = db.query(models.Knowledge).filter(models.Knowledge.id == kid, models.Knowledge.owner_id == current.id).first()
    if not k:
        raise HTTPException(status_code=404, detail="Knowledge not found")
    db.query(models.KnowledgeFolderLink).filter(models.KnowledgeFolderLink.knowledge_id == kid).delete()
    if payload.folder_id:
        db.add(models.KnowledgeFolderLink(knowledge_id=kid, folder_id=payload.folder_id))
    db.commit()
    return {"ok": True}

@router.post("/{kid}/link-issue")
def link_issue(kid: int, payload: schemas.LinkIssueIn, db: Session = Depends(get_db), current=Depends(get_current_user)):
    # ensure ownership
    k = db.query(models.Knowledge).filter(models.Knowledge.id == kid, models.Knowledge.owner_id == current.id).first()
    if not k:
        raise HTTPException(status_code=404, detail="Knowledge not found")
    issue = db.query(models.Issue).filter(models.Issue.id == payload.issue_id, models.Issue.owner_id == current.id).first()
    if not issue:
        raise HTTPException(status_code=404, detail="Issue not found")
    exists = db.query(models.IssueKnowledgeLink).filter(models.IssueKnowledgeLink.issue_id == issue.id, models.IssueKnowledgeLink.knowledge_id == kid).first()
    if not exists:
        db.add(models.IssueKnowledgeLink(issue_id=issue.id, knowledge_id=kid))
        db.commit()
    return {"ok": True}

@router.post("/{kid}/add_card_from_issue")
def add_card_from_issue(kid: int, payload: schemas.LinkIssueIn, db: Session = Depends(get_db), current=Depends(get_current_user)):
    k = db.query(models.Knowledge).filter(models.Knowledge.id == kid, models.Knowledge.owner_id == current.id).first()
    if not k:
        raise HTTPException(status_code=404, detail="Knowledge not found")
    issue = db.query(models.Issue).filter(models.Issue.id == payload.issue_id, models.Issue.owner_id == current.id).first()
    if not issue:
        raise HTTPException(status_code=404, detail="Issue not found")
    
    # Generate card HTML
    import time
    import random
    card_id = f"{int(time.time()*1000)}{random.randint(100,999)}"
    
    question = issue.title.replace("<", "&lt;").replace(">", "&gt;")
    answer = issue.summary or issue.description or ""
    
    card_html = f"""
      <section class="qa" data-id="{card_id}">
        <h3>{question}</h3>
        {answer}
      </section>
    """
    
    # Append to body
    if k.body:
        k.body += "\n" + card_html
    else:
        k.body = card_html
        
    db.commit()
    return {"ok": True}
